import matplotlib.pyplot as plt
from tqdm import tqdm
import re
from datetime import datetime

"""
查看接口每天X点，调用次数比较，是否有变化
"""

method_t_vv_dic = {}

# 08月01日、08月02日
vv_pre_dic = {}
# 08月01日、08月02日 对应的数据,  【也可以用字典】
vv_lst_dic = {}


def show_plot(x_name: list, precision: list, recall: list, f1: list, AUC: list, path):
    plt.figure(figsize=(18, 6))
    plt.plot(x_name, precision, 'or-', recall, '^g-', f1, '*b-', AUC, '.y-.')
    plt.legend(['precision', 'recall', 'f1', 'AUC'], loc='upper right')
    plt.savefig(path, dpi=300)
    plt.show()
    pass


def show_plot(x_name: list, pre_dic: dict, lst_dic: dict, save_path):
    fig = plt.figure(figsize=(18, 6))
    ax1 = fig.add_subplot(1, 2, 1)
    ax2 = fig.add_subplot(1, 2, 2)
    # plt.plot(x_name, precision, 'or-', recall, '^g-', f1, '*b-', AUC, '.y-.')
    max_y = 1000

    for pre_y in pre_dic["y_list"]:
        vv_list = list(pre_y[0])
        # 补全X轴的值
        while len(vv_list) < len(x_name):
            vv_list.append(0)
        ax1.plot(x_name, vv_list)
        # 获取最Y轴最大值
        if max(vv_list) > max_y:
            max_y = max(vv_list)

    for lst_y in lst_dic["y_list"]:
        vv_list = list(lst_y[0])
        # 补全X轴的值
        while len(vv_list) < len(x_name):
            vv_list.append(0)
        ax2.plot(x_name, vv_list)
        # 获取最Y轴最大值
        if max(vv_list) > max_y:
            max_y = max(vv_list)

    ax1.legend(pre_dic["title"], loc='upper right')
    ax2.legend(lst_dic["title"], loc='upper right')
    ax1.set_ylim(0, y_axis_ceil(max_y))
    ax2.set_ylim(0, y_axis_ceil(max_y))
    plt.savefig(save_path, dpi=300)
    plt.show()
    pass


def draw_plot(pre_dic: dict, lst_dic: dict):
    """

    :param pre_dic: key : ["08-01", "08-02"]  ,value [[0.5, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6],[0.5, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6]]
    :param lst_dic:
    :return:
    """

    x_name = ['08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']
    save_file = f'{datetime.now().strftime("%Y%m%d%H%M%S")}.png'
    show_plot(x_name, pre_dic, lst_dic, save_file)


def extraction_data(log_file_name, title):
    # 08月01日、08月02日 对应的数据,  【也可以用字典】
    vv_list = []  # [[0.5, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6],[0.5, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6, 0.8, 0.9, 0.5, 0.6]]
    with open(log_file_name, 'r', encoding='utf-8') as f:
        # 初始化 QueryEcgReportList_09,10 -- 按小时进行区分，每小时接口被请求的次数
        method_h_vv_dic = {}
        for idx, line in tqdm(enumerate(f.readlines())):
            # if (idx > 5):
            #     break
            # print('%s %s' % (idx, line))

            # 使用正则表达式匹配日和小时部分
            # 这里的正则表达式解释如下：
            # \d{4}-\d{2}-(\d{2}) 匹配年份-月份-日，其中日部分被捕获组(\d{2})捕获
            # \s+ 匹配一个或多个空白字符（在这个例子中是一个空格）
            # (\d{2}): 匹配小时部分，小时部分也被捕获组(\d{2})捕获
            # 注意：后面的分钟、秒和毫秒部分没有被捕获，因为我们只对日和小时感兴趣
            match_date_hour = re.search(r'\d{4}-\d{2}-(\d{2})\s+(\d{2}):', line)
            if match_date_hour:
                # 如果找到匹配项，则提取捕获组中的内容
                day = match_date_hour.group(1)  # 第一个捕获组是日
                hour = match_date_hour.group(2)  # 第二个捕获组是小时
                # print(f"日: {day}, 小时: {hour}")  # 输出: 日: 01, 小时: 06

            # 跳过8点前，18点后的数据
            if int(hour) < 8 or int(hour) > 18:
                continue
            # 找出接口名，前面有斜杠（/） 后面跟着逗号（,）结束
            match_method = re.search(r'/([^/]+)(?=,)', line)
            if match_method:
                api_method = match_method.group(1)
                if api_method == "QueryEcgReportList":
                    # print('%s %s' % (idx, api_method + "_" + hour))

                    method_t_vv_dic[api_method] = method_t_vv_dic.get(api_method, 0) + 1
                    method_h_vv_dic[api_method + "_" + hour] = method_h_vv_dic.get(api_method + "_" + hour, 0) + 1
        print(f"最高访问次数：{max(method_h_vv_dic.values())}")
        # 添加接口访问次数到数组
        vv_list.append(method_h_vv_dic.values())

        # # print test
        # for idx, key in enumerate(method_h_vv_dic.keys()):
        #     h_vv_line = f" {key}, {method_h_vv_dic[key]}"
        #     print(h_vv_line)
        return vv_list


def write_visit_view():
    """
    记录接口访问次数
    :return:
    """
    with open('VisitView.csv', 'w') as file:
        for idx, key in enumerate(method_t_vv_dic.keys()):
            line = f" {key}, {method_t_vv_dic[key]}"
            print(line)
            file.write(line + "\n")


def run():
    # region 开发前的日志
    vv_title = ["08-04", "08-05", "08-06", "08-07", "08-08", "08-09"]  # 这样到方法里取不到值
    vv_pre_dic["title"] = vv_title
    vv_pre_dic["y_list"] = []
    for day in vv_title:
        log_file_name = f'ecg_process_trace/2024-{day}_trace.log'
        vv_list = extraction_data(log_file_name, day)

        vv_pre_dic["y_list"].append(vv_list)
    # endregion

    # region 开发后的日志
    vv_title = ["08-12", "08-13", "08-14"]  # 这样到方法里取不到值
    vv_lst_dic["title"] = vv_title
    vv_lst_dic["y_list"] = []
    for day in vv_title:
        log_file_name = f'ecg_process_trace/2024-{day}_trace.log'
        vv_list = extraction_data(log_file_name, day)
        vv_lst_dic["y_list"].append(vv_list)
    # endregion

    # write_visit_view()
    draw_plot(vv_pre_dic, vv_lst_dic)


def y_axis_ceil(num, base=1000):
    """
    1. num + base - 1 确保即使num是base的倍数。
    2. // 是整数除法运算符，它会向下取整到最接近的整数。
    3. 我们将结果乘以base，以确保结果是base的倍数。
    :param num:
    :param base:
    :return:
    """
    return ((num + base - 1) // base) * base


if __name__ == "__main__":
    run()

